package project.gui;


import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.BoxLayout;
import java.awt.GridLayout;
import javax.swing.border.EtchedBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.Dimension;
import javax.swing.JSplitPane;
import java.awt.Component;
import javax.swing.Box;
import java.awt.Window.Type;
import javax.swing.JButton;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JCheckBox;
import javax.swing.JRadioButton;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.plaf.SliderUI;

import project.map.OccupancyGridMap;
import project.map.Position;
import project.robot.Robot;
import project.robot.navigation.ChessGridNavigator;
import project.robot.navigation.LineGridNavigator;
import project.simulador.NavegacionSimulada;

public class Principal extends JFrame {

	private JPanel contentPane;
	private JTextField txtAncho;
	private JTextField txtAlto;
	private JTextField txtPosX;
	private JTextField txtPosY;
	private JTextField txtPosO;
	private JTextField txtNavigateX;
	private JTextField txtNavigateY;
	private JTextField txtNavigateO;
	private JPanel pnlGrilla;
	private JButton btnIniciarMapeo;
	private JButton btnDetenerMapeo;
	private JButton btnPausarMapeo;
	private JButton btnInicio;

	private Robot robot;
	private OccupancyGridMap mapaRobot;		// el mapa que el robot construye
	private MapWorker mapeadorGUI;
	private Grid grilla =  new Grid(10,10);
	private JTextField txtangulo;
	private JSlider sliderMaxRange;
	private JSlider sliderScanDelay;
	private JSlider sliderConfianza;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				new Principal().setVisible(true);
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Principal() {
		setTitle("Mapeador GUI");
		setMinimumSize(new Dimension(810, 650));
		setPreferredSize(new Dimension(810, 650));
		setSize(new Dimension(810, 650));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 605, 442);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		pnlGrilla = new JPanel();
		pnlGrilla.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		pnlGrilla.setBounds(10, 11, 525, 554);
		pnlGrilla.add(grilla);
		contentPane.add(pnlGrilla);
		pnlGrilla.setLayout(new GridLayout(1, 0, 0, 0));

		JLabel lblParametrosRobot = new JLabel("Mapa");
		lblParametrosRobot.setBounds(545, 11, 117, 14);
		contentPane.add(lblParametrosRobot);

		JPanel panel_3 = new JPanel();
		panel_3.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		panel_3.setBounds(545, 30, 239, 34);
		contentPane.add(panel_3);
		panel_3.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		JLabel lblAncho = new JLabel("Ancho:");
		panel_3.add(lblAncho);

		txtAncho = new JTextField();
		panel_3.add(txtAncho);
		txtAncho.setColumns(5);

		JLabel lblAlto = new JLabel("Alto:");
		panel_3.add(lblAlto);

		txtAlto = new JTextField();
		panel_3.add(txtAlto);
		txtAlto.setColumns(5);

		JPanel panel_1 = new JPanel();
		panel_1.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		panel_1.setBounds(545, 162, 239, 227);
		contentPane.add(panel_1);

		JLabel lblUltrasonidoAlcance = new JLabel("Alcance maximo [cm]");
		lblUltrasonidoAlcance.setHorizontalAlignment(SwingConstants.LEFT);
		panel_1.add(lblUltrasonidoAlcance);

		sliderMaxRange = new JSlider();
		sliderMaxRange.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent arg0) {
			}
		});
		sliderMaxRange.setMajorTickSpacing(20);
		sliderMaxRange.setMaximum(180);
		sliderMaxRange.setValue(100);
		sliderMaxRange.setSnapToTicks(true);
		sliderMaxRange.setPaintTicks(true);
		sliderMaxRange.setPaintLabels(true);
		sliderMaxRange.setMinorTickSpacing(20);
		sliderMaxRange.setMinimum(40);
		panel_1.add(sliderMaxRange);

		JLabel lblFrecuenciaDeEscaneo = new JLabel("Delay entre escaneos [ms]");
		lblFrecuenciaDeEscaneo.setHorizontalAlignment(SwingConstants.LEFT);
		panel_1.add(lblFrecuenciaDeEscaneo);

		sliderScanDelay = new JSlider();
		sliderScanDelay.setValue(1000);
		sliderScanDelay.setSnapToTicks(true);
		sliderScanDelay.setPaintTicks(true);
		sliderScanDelay.setPaintLabels(true);
		sliderScanDelay.setMinorTickSpacing(100);
		sliderScanDelay.setMaximum(1000);
		sliderScanDelay.setMajorTickSpacing(200);
		panel_1.add(sliderScanDelay);

		JLabel label = new JLabel("Grado de confianza");
		label.setHorizontalAlignment(SwingConstants.LEFT);
		panel_1.add(label);

		sliderConfianza = new JSlider();
		sliderConfianza.setValue(5);
		sliderConfianza.setSnapToTicks(true);
		sliderConfianza.setPaintTicks(true);
		sliderConfianza.setPaintLabels(true);
		sliderConfianza.setMinorTickSpacing(1);
		sliderConfianza.setMaximum(15);
		sliderConfianza.setMajorTickSpacing(5);
		panel_1.add(sliderConfianza);

		JLabel lblRobot = new JLabel("Robot");
		lblRobot.setBounds(545, 72, 117, 14);
		contentPane.add(lblRobot);

		JPanel panel_2 = new JPanel();
		panel_2.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		panel_2.setBounds(545, 90, 239, 74);
		contentPane.add(panel_2);
		panel_2.setLayout(new GridLayout(2, 1, 0, 0));

		JLabel lblNewLabel = new JLabel("Posicion Inicial");
		lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
		panel_2.add(lblNewLabel);

		JPanel panel_4 = new JPanel();
		panel_2.add(panel_4);

		JLabel lblNewLabel_1 = new JLabel("X:");
		panel_4.add(lblNewLabel_1);

		txtPosX = new JTextField();
		panel_4.add(txtPosX);
		txtPosX.setColumns(3);

		JLabel lblY = new JLabel("Y:");
		panel_4.add(lblY);

		txtPosY = new JTextField();
		txtPosY.setColumns(3);
		panel_4.add(txtPosY);

		JLabel lblO = new JLabel("O:");
		panel_4.add(lblO);

		txtPosO = new JTextField();
		txtPosO.setColumns(3);
		panel_4.add(txtPosO);

		JPanel panel_5 = new JPanel();
		panel_5.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		panel_5.setBounds(545, 434, 239, 131);
		contentPane.add(panel_5);
		panel_5.setLayout(null);

		JLabel lblNavegarMapa = new JLabel("Navegar Mapa");
		lblNavegarMapa.setBounds(2, 2, 235, 30);
		lblNavegarMapa.setHorizontalAlignment(SwingConstants.CENTER);
		panel_5.add(lblNavegarMapa);

		JPanel panel_6 = new JPanel();
		panel_6.setBounds(2, 33, 235, 95);
		panel_5.add(panel_6);
		panel_6.setLayout(null);

		JLabel label_1 = new JLabel("X:");
		label_1.setBounds(9, 9, 10, 14);
		panel_6.add(label_1);

		txtNavigateX = new JTextField();
		txtNavigateX.setBounds(24, 6, 30, 20);
		txtNavigateX.setColumns(3);
		panel_6.add(txtNavigateX);

		JLabel label_2 = new JLabel("Y:");
		label_2.setBounds(59, 9, 10, 14);
		panel_6.add(label_2);

		txtNavigateY = new JTextField();
		txtNavigateY.setBounds(74, 6, 30, 20);
		txtNavigateY.setColumns(3);
		panel_6.add(txtNavigateY);

		JLabel label_3 = new JLabel("O:");
		label_3.setBounds(109, 9, 12, 14);
		panel_6.add(label_3);

		txtNavigateO = new JTextField();
		txtNavigateO.setBounds(126, 6, 30, 20);
		txtNavigateO.setColumns(3);
		panel_6.add(txtNavigateO);

		JButton btnEnviar = new JButton("Enviar");
		btnEnviar.setBounds(161, 5, 65, 23);
		panel_6.add(btnEnviar);

		txtangulo = new JTextField();
		txtangulo.setBounds(50, 62, 30, 20);
		panel_6.add(txtangulo);
		txtangulo.setColumns(3);

		JButton btnE = new JButton("Rotar");
		btnE.setBounds(85, 61, 61, 23);
		panel_6.add(btnE);

		JButton btnIr = new JButton("Avanzar");
		btnIr.setBounds(151, 61, 75, 23);
		panel_6.add(btnIr);
		btnIr.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robot.goForward(20, 20);
			}
		});
		btnE.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				robot.turn(Integer.parseInt(txtangulo.getText()));
			}
		});
		btnEnviar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {

				Position goal = new Position();
				goal.x = Integer.parseInt(txtNavigateX.getText());
				goal.y = Integer.parseInt(txtNavigateY.getText());
				goal.o = Integer.parseInt(txtNavigateO.getText());

				robot.navigateTo(goal);
			}
		});

		btnInicio = new JButton("Inicio");
		btnInicio.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				inicializar();
			}
		});
		btnInicio.setBounds(545, 400, 80, 23);
		contentPane.add(btnInicio);

		btnIniciarMapeo = new JButton(">");
		btnIniciarMapeo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				mapear();
			}
		});
		btnIniciarMapeo.setEnabled(false);
		btnIniciarMapeo.setBounds(635, 400, 43, 23);
		contentPane.add(btnIniciarMapeo);

		btnDetenerMapeo = new JButton("X");
		btnDetenerMapeo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				detenerMapeo();
			}
		});
		btnDetenerMapeo.setEnabled(false);
		btnDetenerMapeo.setBounds(741, 400, 43, 23);
		contentPane.add(btnDetenerMapeo);

		btnPausarMapeo = new JButton("||");
		btnPausarMapeo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				pausarMapeo();
			}
		});
		btnPausarMapeo.setEnabled(false);
		btnPausarMapeo.setBounds(688, 400, 43, 23);
		contentPane.add(btnPausarMapeo);
	}

	private void inicializar()
	{
		pnlGrilla.remove(grilla);

		grilla= new Grid(Integer.parseInt(txtAncho.getText()),Integer.parseInt(txtAlto.getText()));

		pnlGrilla.add(grilla);

		inicializarRobot();

		btnIniciarMapeo.setEnabled(true);
		this.pack();
	}

	private void mapear()
	{
		btnIniciarMapeo.setEnabled(false);
		btnDetenerMapeo.setEnabled(true);
		btnPausarMapeo.setEnabled(true);
		btnInicio.setEnabled(false);

		robot.setPause(false);

		mapeadorGUI = new MapWorker(robot, sliderConfianza.getValue());	
		mapeadorGUI.execute();
	}

	private void pausarMapeo()
	{
		if (btnPausarMapeo.getText().equals("||"))
		{				
			robot.setPause(true);
			btnPausarMapeo.setText(">");
		}else
		{
			robot.setPause(false);
			btnPausarMapeo.setText("||");
		}
	}

	private void detenerMapeo()
	{
		btnDetenerMapeo.setEnabled(false);
		btnPausarMapeo.setEnabled(false);
		btnIniciarMapeo.setEnabled(false);
		btnInicio.setEnabled(true);

	}

	private void inicializarRobot()
	{
		//Crear e inicializar el mapa que tiene que llenar el robot.
		mapaRobot = new OccupancyGridMap(Integer.parseInt(txtAncho.getText()),Integer.parseInt(txtAlto.getText()));
		mapaRobot.addListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				grilla.updateCell((int[][])e.getSource(), e.getID(), e.getModifiers());
			}
		});

		//Crear e inicializar el sistema de navegacion.
		ChessGridNavigator navegador = new ChessGridNavigator();

	//	navegador.setLinea(550);
	//	navegador.setSuelo(250);
	//	navegador.setKp(0.1F);
	//	navegador.setAnchoRobot(10.5F);
	//	navegador.setDiametroRuedas(4.32F);

		//crear el robot
		robot = new Robot(this.sliderMaxRange.getValue(), this.sliderScanDelay.getValue());
		robot.setNavegacion(navegador);
		robot.setMapa(mapaRobot);
		robot.setPosActual(new Position(Integer.parseInt(txtPosX.getText()), Integer.parseInt(txtPosY.getText()),Integer.parseInt(txtPosO.getText())));
		robot.startDetection();
	}
}

